﻿using System;
using System.Collections.Generic;
using System.IdentityModel.Tokens.Jwt;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Casamiel.API.Application;
using Casamiel.API.Application.Commands;
using Casamiel.API.Application.Models;
using Casamiel.API.Infrastructure;
using Casamiel.API.Infrastructure.Filters;
using Casamiel.Application.Commands;
using Casamiel.Common;
using Casamiel.Common.Extensions;
using MediatR;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.DependencyInjection;
using NLog;

// For more information on enabling Web API for empty projects, visit https://go.microsoft.com/fwlink/?LinkID=397860

namespace Casamiel.API.Controllers.V3
{
    /// <summary>
    /// 
    /// </summary>
    [Produces("application/json")]
    [ApiVersion("3.0")]
    [Route("api/v{version:apiVersion}/Login")]//{version:apiVersion}
    [Authorize]
    [ApiController]
    public class LoginController : BaseController
    {
        private readonly NLog.ILogger logger = LogManager.GetLogger("BizInfo");

        private readonly IServiceScopeFactory _scopeFactory;

        /// <summary>
        /// 
        /// </summary>
        /// <param name="serviceScopeFactory"></param>
        public LoginController(IServiceScopeFactory serviceScopeFactory)
        {
            _scopeFactory = serviceScopeFactory;
        }

        /// <summary>
        /// 登陆
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        [HttpPost]
        [Route("[action]")]
        public async Task<IActionResult> Login([FromBody] LoginReq data)
        {
            if (data == null) {
                throw new ArgumentNullException(nameof(data));
            }
            using var scope = _scopeFactory.CreateScope();
            var _mobileCheckCode = scope.ServiceProvider.GetRequiredService<IMobileCheckCode>();
            var _mediator = scope.ServiceProvider.GetRequiredService<IMediator>();
            ConsoleHelper.DoLog(data, Request);
            var loginInfo = LoginInfo;
            var source = loginInfo.Item2;
            //var userAgent = Request.GetUserAgent();
            int loginType = loginInfo.Item1;

            var sucess = await _mobileCheckCode.CheckSmsCodeAsync(data.Mobile, data.Yzm, false).ConfigureAwait(false);
            var smscode = sucess["code"].ToInt16(-9);
            if (smscode != 0) {
                return new JsonResult(new { code = smscode, msg = sucess["msg"].ToString() });
            }

            var command = new LoginCommand { InvitationCode = data.InvitationCode, Mobile = data.Mobile, LoginType = loginType, Registration_Id = data.Registration_Id, RequestUrl = Request.GetShortUri(), UserIP = Request.GetUserIp(), Source = source };
            var result = await _mediator.Send(command).ConfigureAwait(false);
            var member = result.Item1;
            var memberdata = new { Mobile = member.Mobile, Nick = member.Nick, Birthday = member.Birthday, Sex = member.Sex, TrueName = member.TrueName, Email = member.Email, cardno = result.Item3 };

            var cmd = new GetMemberInfoCommand(data.Mobile);
            var result2 = await _mediator.Send(cmd).ConfigureAwait(false);
            //return new JsonResult(new { code = 0, data = result.Item2, member = memberdata });
            return Ok(new { code = 0, content = new { data = result.Item2, member = result2.Content }, msg = "" });
        }

        /// <summary>
        /// 会员token刷新
        /// </summary>
        /// <param name="data"></param>
        /// <param name="token"></param>
        /// <returns></returns>
        [HttpPost]
        [Route("[action]")]

        [TypeFilterAttribute(typeof(CheckTokenAttribute))]
        public async Task<IActionResult> RefreshUserToken(
        [FromBody] UserTokenDto data, [FromHeader(Name = "u-token")] string token)
        {
            if (data == null) {
                throw new ArgumentNullException(nameof(data));
            }

            Common.ConsoleHelper.DoLog(data, Request);
            //var userAgent = Request.Headers["User-Agent"].ToString() == "" ? Request.Headers["UserAgent"].ToString() : Request.Headers["User-Agent"].ToString();
            //int loginType = userAgent.ToUpper().Contains("CASAMIEL") ? 1 : 2;
            //if (userAgent.Contains("MicroMessenger"))
            //{
            //    loginType = 3;//微信端
            //}
            var loginInfo = this.LoginInfo;

            var handler = new JwtSecurityTokenHandler();
            JwtSecurityToken dtoken = handler.ReadJwtToken(token);
            var rsa = new RSAHelper(RSAType.RSA2, Encoding.UTF8, RSAHelper.privateKey, RSAHelper.publicKey);

            var exp = dtoken.Payload.Exp;
            string mobile = rsa.Decrypt(dtoken.Payload.Jti);
            if (exp < new DateTimeOffset(DateTime.Now).ToUnixTimeSeconds()) {
                var a = new { code = -14, msg = "登录凭证已过期，请重新登陆" };
                return new JsonResult(a);
            }
            using var scope = _scopeFactory.CreateScope();
            var _mediator = scope.ServiceProvider.GetRequiredService<IMediator>();
            
            var command = new CreateMemberAccessTokenComand(mobile, loginInfo.Item1, data.registration_Id) { RequestUrl = Request.GetShortUri(), UserIP = Request.GetUserIp() };
            var result = await _mediator.Send(command).ConfigureAwait(false);
            var cmd = new GetMemberInfoCommand(mobile);
            var result2 = await _mediator.Send(cmd).ConfigureAwait(false);
            //var member = await _memberService.FindAsync<ICasaMielSession>(mobile).ConfigureAwait(false);
            //var memberdata = new { Mobile = member.Mobile, Nick = member.Nick, Birthday = member.Birthday, Sex = member.Sex, TrueName = member.TrueName, Email = member.Email };
            //return Ok(new { code = 0, data = result, member = memberdata });
            return Ok(new { code = 0, data = result, content = new { data = result, member = result2.Content }, msg = "" });

        }

    }
}
